using System;
using System.Collections.Generic;
using System.Text;
using Pixysoft.Framework.Configurations;
namespace Pixysoft.Framework.Reports.Core
{
    class ReportCollection<T> : IEnumerable<T>, IEnumerator<T>
    {
        protected int index = -1;

        protected List<T> list = new List<T>();

        public ReportCollection(List<T> list)
        {
            this.list = list;
        }

        public int Count
        {
            get { return list.Count; }
        }

        public bool Contains(T value)
        {
            return list.Contains(value);
        }

        public T this[int index]
        {
            get
            {
                if (index < 0 || index > list.Count - 1)
                    return default(T);

                return list[index];
            }
        }

        public T RemoveAt(int index)
        {
            T row = this[index];

            if (row == null)
                return row;

            Remove(row);

            return row;
        }

        public void Remove(T value)
        {
            list.Remove(value);
        }

        public void RemoveAll()
        {
            list.Clear();
        }

        public IEnumerator<T> GetEnumerator()
        {
            return this;
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this;
        }

        public T Current
        {
            get { return this[index]; }
        }

        public void Dispose()
        {
            Reset();
        }

        object System.Collections.IEnumerator.Current
        {
            get { return this[index]; }
        }

        public bool MoveNext()
        {
            if (index >= list.Count - 1)
                return false;

            index++;

            return true;
        }

        public void Reset()
        {
            index = -1;
        }
    }

    class ReportTableRowCollection : ReportRowCollection
    {
        public ReportTableRowCollection(List<IReportColumn> columns, List<IReportRow> rows)
            : base(columns, rows) { }

        public override void Add(IReportRow row)
        {
            if (row.Setting != null && row.Setting.GetChildrenSettings().Length > 0)
                throw new Exception("row setting need no children.");

            base.Add(row);
        }
    }

    class ReportRowCollection : ReportCollection<IReportRow>, IReportRowCollection
    {
        List<IReportColumn> columns = null;

        public ReportRowCollection(List<IReportColumn> columns, List<IReportRow> rows)
            : base(rows)
        {
            this.columns = columns;
        }

        public IReportRow this[string headerName]
        {
            get
            {
                foreach (IReportRow row in list)
                {
                    if (string.Equals(headerName, row.Setting.HeaderName, StringComparison.OrdinalIgnoreCase))
                        return row;
                }

                return null;
            }
        }

        public virtual void Add(IReportRow row)
        {
            if (!list.Contains(row))
                list.Add(row);
        }

        public IReportRow NewRow(string headerName, string rowIdentifier, IReportRowSetting setting)
        {
            ReportRow row = new ReportRow(headerName, rowIdentifier, base.Count, setting, columns);
            return row;
        }

        public IReportRow GetRow(string rowIdentifier)
        {
            foreach (IReportRow row in list)
                if (string.Equals(row.Identifier, rowIdentifier))
                    return row;

            return null;
        }

        public IReportRow[] ToArray()
        {
            return base.list.ToArray();
        }
    }

    class ReportTableColumnCollection : ReportColumnCollection
    {
        public ReportTableColumnCollection(List<IReportColumn> columns)
            : base(columns)
        {
        }

        public override void Add(IReportColumn column)
        {
            if (column.Setting != null && column.Setting.GetChildrenSettings().Length > 0)
                throw new Exception("column setting need no children.");

            base.Add(column);
        }
    }

    class ReportColumnCollection : ReportCollection<IReportColumn>, IReportColumnCollection
    {
        public ReportColumnCollection(List<IReportColumn> columns)
            : base(columns)
        {
        }

        public IReportColumn this[string headerName]
        {
            get
            {
                foreach (IReportColumn column in list)
                {
                    if (string.Equals(headerName, column.Setting.HeaderName, StringComparison.OrdinalIgnoreCase))
                        return column;
                }

                return null;
            }
        }

        public virtual void Add(IReportColumn column)
        {
            if (!list.Contains(column))
                list.Add(column);
        }

        public IReportColumn[] ToArray()
        {
            return base.list.ToArray();
        }

        public IReportColumn NewColumn(string headerName, int columnIndex, IReportColumnSetting setting)
        {
            return new ReportColumn(headerName, columnIndex, setting);
        }
    }

    class ReportCellCollection : ReportCollection<IReportCell>, IReportCellCollection
    {
        public ReportCellCollection(List<IReportCell> cells)
            : base(cells)
        {
        }

        public IReportCell GetCell(int columnIndex)
        {
            return base[columnIndex];
        }

        public new object this[int columnIndex]
        {
            get
            {
                IReportCell cell = base[columnIndex];

                if (cell == null)
                    return null;

                return cell.Value;
            }
        }
    }
}
